package edu.tfh.s2.ehkbot.daten;

import edu.tfh.s2.ehkbot.gerete.aktoren.BiStateAktor;
import edu.tfh.s2.ehkbot.gerete.aktoren.MotorAktor;
import edu.tfh.s2.ehkbot.gerete.sensoren.BarcodeScanner;
import edu.tfh.s2.ehkbot.gerete.sensoren.IndoorGPS;
import edu.tfh.s2.ehkbot.gerete.sensoren.Kamera;
import edu.tfh.s2.ehkbot.gerete.sensoren.Sensor;
import edu.tfh.s2.ehkbot.gerete.sensoren.BarcodeScanner.BarcodeScannerState;
import edu.tfh.s2.ehkbot.inventar.Warenbestand;
import edu.tfh.s2.ehkbot.inventar.WarenboxRegal;
import edu.tfh.s2.ehkbot.steuerung.BusAdresse;
import edu.tfh.s2.ehkbot.steuerung.Karte;
import edu.tfh.s2.ehkbot.steuerung.schnittstellen.Netzwerk;

/**
 * InitFactory ist eine Factory zum erzeugen von den EHKBot System Komponenenten, mit Hilfe vom State Pattern
 * ist sie in der Lage je nach Status unterschiedliche Objekte zu erzeugen z. B. für Simulation und
 * Realbetrieb. Dadurch wird die Initialiesierung Phase unabhänig von äußeren gegebenheiten.
 * 
 * @author s2zehn
 */
public class InitFactory {

	/**
	 * Siehe State Pattern
	 */
	public interface InitFactoryState {
		/**
		 * @return Den Barcodescanner State.
		 */
		public BarcodeScanner getBarcodeScanner();

		/**
		 * @return Einen BiStateAktor.
		 */
		public BiStateAktor getBiStateAktor(BusAdresse busAdresse);

		/**
		 * @return Den passenden IndoorGPS.IndoorGPSState.
		 */
		public IndoorGPS.IndoorGPSState getIndoorGPS();

		/**
		 * @return Den Kamera State.
		 */
		public Kamera getKamera();

		/**
		 * @return Die für das System gültige Karte.
		 */
		public Karte getKarte();

		/**
		 * @param busAdd
		 *            Die BusAdresse mit der, der MotorAktor initaliesiert wird.
		 * @return Ein MotorAktor
		 */
		public MotorAktor getMotorAktor(BusAdresse busAdd);

		/**
		 * @return Ein NetzwerkSate
		 */
		public Netzwerk.NetzwerkState getNetzwerk();

		/**
		 * @param busAdresse
		 *            Die BusAdresse mit der, der Sensor initaliesiert wird.
		 * @return Ein Sensor.
		 */
		public Sensor getSensor(BusAdresse busAdresse);

		/**
		 * @return Den Warenbestand.
		 */
		public Warenbestand getWarenbestand();

		/**
		 * @return Das Warenboxreal.
		 */
		public WarenboxRegal getWarenboxregal();

		/**
		 * @return Den Zeitgeber.
		 */
		public Zeitgeber.ZeitgeberState getZeitgeber();

	}

	/**
	 * Siehe Singelton Pattern.
	 */
	private static InitFactory instance;

	/**
	 * Siehe Singelton Pattern.
	 * 
	 * @return Die einzige Instanz von InitFactory
	 */
	public static InitFactory getInstance() {
		if (instance == null) {
			instance = new InitFactory();
		}
		return instance;
	}

	/**
	 * Siehe State Pattern.
	 */
	private InitFactoryState state = null;

	/**
	 * privater Konstruktor, siehe Singelton Pattern.
	 */
	private InitFactory() {
	}

	/**
	 * Übergibt den Methodenanfage an das State weiter. Siehe InitFactoryState.getBarcodeScanner()
	 * 
	 * @return {@link InitFactoryState.getBarcodeScanne}
	 */
	public BarcodeScanner getBarcodeScanner() {
		return state.getBarcodeScanner();
	}

	/**
	 * Übergibt den Methodenanfage an das State weiter. Siehe InitFactoryState.getBiStateAktor()
	 * 
	 * @param busAdresse
	 *            Siehe InitFactoryState.getBiStateAktor()
	 * @return Siehe InitFactoryState.getBiStateAktor()
	 */
	public BiStateAktor getBiStateAktor(BusAdresse busAdresse) {
		return state.getBiStateAktor(busAdresse);
	}

	/**
	 * Übergibt den Methodenanfage an das State weiter. Siehe InitFactoryState.getIndoorGPS()
	 * 
	 * @return Siehe InitFactoryState.getIndoorGPS()
	 */
	public IndoorGPS.IndoorGPSState getIndoorGPS() {
		return state.getIndoorGPS();
	}

	/**
	 * Übergibt den Methodenanfage an das State weiter. Siehe InitFactoryState.getKamera()
	 * 
	 * @return Siehe InitFactoryState.getZeitgeber()
	 */
	public Kamera getKamera() {
		return state.getKamera();
	}

	/**
	 * Übergibt den Methodenanfage an das State weiter. Siehe InitFactoryState.getKarte()
	 * 
	 * @return Siehe InitFactoryState.getKarte()
	 */
	public Karte getKarte() {
		return state.getKarte();
	}

	/**
	 * Übergibt den Methodenanfage an das State weiter. Siehe InitFactoryState.getMotorAktor()
	 * 
	 * @param busAdd
	 *            Siehe InitFactoryState.getMotorAktor()
	 * @return Siehe InitFactoryState.getMotorAktor()
	 */
	public MotorAktor getMotorAktor(BusAdresse busAdd) {
		return state.getMotorAktor(busAdd);
	}

	/**
	 * Übergibt den Methodenanfage an das State weiter. Siehe InitFactoryState.getNetzwerk()
	 * 
	 * @return Siehe InitFactoryState.getNetzwerk()
	 */
	public Netzwerk.NetzwerkState getNetzwerk() {
		return state.getNetzwerk();
	}

	/**
	 * Übergibt den Methodenanfage an das State weiter. Siehe InitFactoryState.getSensor()
	 * 
	 * @param busAdresse
	 *            Siehe InitFactoryState.getSensor()
	 * @return Siehe InitFactoryState.getSensor()
	 */
	public Sensor getSensor(BusAdresse busAdresse) {
		return state.getSensor(busAdresse);
	}

	/**
	 * Übergibt den Methodenanfage an das State weiter. Siehe InitFactoryState.getWarenbestand()
	 * 
	 * @return Siehe InitFactoryState.getWarenbestand()
	 */
	public Warenbestand getWarenbestand() {
		return state.getWarenbestand();
	}

	/**
	 * Übergibt den Methodenanfage an das State weiter. Siehe InitFactoryState.getWarenboxregal()
	 * 
	 * @return Siehe InitFactoryState.getWarenboxregal()
	 */
	public WarenboxRegal getWarenboxregal() {
		return state.getWarenboxregal();
	}

	/**
	 * Übergibt den Methodenanfage an das State weiter. Siehe InitFactoryState.getZeitgeber()
	 * 
	 * @return Siehe InitFactoryState.getZeitgeber()
	 */
	public Zeitgeber.ZeitgeberState getZeitgeber() {
		return state.getZeitgeber();
	}

	/**
	 * Setzt den State von initFactory.
	 * 
	 * @param initFactory
	 *            Der neue State für initFactory.
	 */
	public void setState(InitFactoryState initFactory) {
		state = initFactory;
	}
}
